import {createSlice, createAsyncThunk} from '@reduxjs/toolkit';
import {fetchTrendingRepo} from '../api/trending';
import {setStorage, getStorage, removeStorage} from '../utils/storage';
import isEmpty from 'lodash/isEmpty';

const storeKey = 'get/fetchTrending';

export const fetchTrending = createAsyncThunk(storeKey, res => {
  return getStorage(storeKey).then(value => {
    const {data = {}, time} = value || {};
    const now = new Date().getTime();

    if (isEmpty(data[res.key]) || now - time > 60 * 60 * 1000 || res.refresh) {
      if (!isEmpty(data[res.key])) {
        removeStorage(storeKey);
      }
      return fetchTrendingRepo(res.key, 'javascript');
    }
    return data;
  });
});

const trendingReducer = createSlice({
  name: 'trending',
  initialState: {
    trendingData: {},
    refresh: false,
  },
  reducers: {
    changeTrendingData(state, action) {
      const {item, key} = action.payload;
      state.trendingData[key] = state.trendingData[key].map(i =>
        i.id === item.id ? item : i,
      );
    },
  },
  extraReducers(builder) {
    builder
      .addCase(fetchTrending.pending, (state, action) => {
        const {refresh} = action.meta.arg;
        if (refresh) {
          state.refresh = true;
        }
      })
      .addCase(fetchTrending.fulfilled, (state, action) => {
        const {key, refresh} = action.meta.arg;
        const {items} = action.payload;
        const prevTrendingData = state.trendingData;
        state.trendingData = {
          ...prevTrendingData,
          [key]: items,
        };
        if (refresh) {
          state.refresh = false;
        }

        setStorage(storeKey, {
          data: state.trendingData,
          time: new Date().getTime(),
        });
      })
      .addCase(fetchTrending.rejected, (state, action) => {
        const {refresh} = action.meta.arg;
        if (refresh) {
          state.refresh = false;
        }
      });
  },
});

export const {changeTrendingData} = trendingReducer.actions;
export default trendingReducer.reducer;
